# OFFICIAL ANIMATED IKA LOGO
# art by Overkill
# code by Thrasher
# @2007
# (verified to work in ika 0.62)

# -----------------------------

import ika
import math

import fps as FPS
import rotate

path = __name__

# ---

squid_img = ika.Image("%s/squid.png" % path)
i_img = ika.Image("%s/letter_i.png" % path)
k_img = ika.Image("%s/letter_k.png" % path)
a_img = ika.Image("%s/letter_a.png" % path)
ex_img = ika.Image("%s/exclam.png" % path)

# ---

scale_x, scale_y = ika.Video.xres / 320, ika.Video.yres / 240
min_scale = min(scale_x, scale_y)
scale_x = min_scale
scale_y = min_scale

# ---

sfx_bubbles = ika.Music("%s/bubbles.ogg" % path)
sfx_bubbles.volume = 0.4
sfx_bubbles.loop = True

sfx_splash = ika.Sound("%s/splash.ogg" % path)
#sfx_splash.volume = 0.0
#sfx_splash.Play()
sfx_splash.volume = 0.6

sfx_thud = [ika.Sound("%s/thud.ogg" % path) for i in range(4)]
sfx_thud[0].volume = .5
sfx_thud[1].volume = .5
sfx_thud[2].volume = .5
sfx_thud[3].volume = .5
sfx_thud[0].pan = 0
sfx_thud[1].pan = .7
sfx_thud[2].pan = 1.3
sfx_thud[3].pan = 2
sfx_thud[0].pitchshift = 3
sfx_thud[1].pitchshift = 0
sfx_thud[2].pitchshift = 2
sfx_thud[3].pitchshift = 1

sfx_giggle = [ika.Sound("%s/giggle.ogg" % path) for i in range(5)]

for i in range(5):
    sfx_giggle[i].pan = [0, -.5, .5, -1, 1][i]
    sfx_giggle[i].volume = [1, .5, .4, .2, .2][i]
    sfx_giggle[i].pitchshift = [0, 1, 1, 3, 4][i]
    
sfx_splat = ika.Sound("%s/splat.ogg" % path)
sfx_fall = ika.Sound("%s/fall.ogg" % path)
sfx_fall.volume = .4

# ---
class Bubble(object):
    
    def __init__(self, x, y, size, spd):
        self.x = x
        self.y = y
        self.size = size
        self.speed = spd
        self.x_spd = 0
    
    def draw(self):
        
        if self.y < 240:
            self.bubble.ScaleBlit(int(self.x), int(self.y), self.size, self.size)
    
    def update(self, xupd=False):
        
        if xupd:
            self.x += ika.Random(-self.x_rand, self.x_rand+1)
        self.x += self.x_spd
        self.x_spd *= 1.02
        self.y -= self.speed
        
        return (self.y + self.size) < 0
        
    x_rand = 2
    bubble = ika.Image("%s/bubble.png" % path)
    
def execute(bg=ika.RGB(172,208,193), fade=True, anim_in=True, idle_anim=True, anim_out=True, fps=60, time=300, button=ika.Input.enter, sounds=True):
    
    fpsman = FPS.FPSManager(fps)
    
    timer = 0
    
    squid_final =   (7,  25 )
    i_final =       (139,56 )
    k_final =       (173,29 )
    a_final =       (224,109)
    ex_final =      (277,33 )
    
    squid_ang, i_ang, k_ang, a_ang, ex_ang = (0,)*5

    i_old_pos = list()
    k_old_pos = list()
    a_old_pos = list()
    ex_old_pos = list()
    
    bubbles = list()
    
    min_bubbles = 30
    max_bubbles = 80
    
    def handleBubbles(new=True):
       
        if new:
            
            seed = ika.Random(min_bubbles, max_bubbles)
               
            while len(bubbles) < seed:
                
                size = ika.Random(20, 40)
                x = ika.Random(-size, 320)
                y = ika.Random(240, 320)
                ix = x
                ix2 = x + size
                
                spd = ika.Random(60, 100)
                while size > 10:
                    bubbles.append(Bubble(x, y, size, spd/25))
                    #x = ika.Random(ix, ix2 - size)
                    y += size + 5
                    size -= 15
                    spd = max(60, ika.Random(spd-10, spd+1))
        
        ofs = 0
        idxes = []
        for i,b in enumerate(bubbles):
            if idle_anim or anim_in or anim_out:
                die = b.update(timer%5 == 0)
                if die:
                    idxes.append(i-ofs)
                    ofs += 1
            b.draw()            
        for i in idxes:
            bubbles.pop(i)

    wholeAlpha = 255
    endAlpha = 0
        
    fadeSpeed = 10
    
    # ---
    
    if sounds:
        sfx_bubbles.Play()
    
    # ---
    # fade in
    
    squid_x, squid_y = squid_final
    i_x, i_y = i_final
    k_x, k_y = k_final
    a_x, a_y = a_final
    ex_x, ex_y = ex_final
        
    fpsman.sync()

    squid_cx = squid_x + squid_img.width / 2
    squid_cy = squid_y + squid_img.height / 2

    if anim_in:
        
        done = False
        
        timer = 0
        
        i_x = -(320 - i_x) * 2
        k_x = -(320 - k_x) * 2
        a_x = -(320 - a_x) * 2
        ex_x = -(320 - ex_x) * 2
        
        i_ang = 45
        k_ang = 90
        a_ang = 150
        ex_ang = 0
        
        i_spd = 4.2
        k_spd = 4.2
        a_spd = 4.7
        ex_spd = 5
        
        i_jump = 55
        k_jump = 50
        a_jump = 45
        ex_jump = 40
        min_jump = 1
        
        squid_scale = 0.01
        
        num_shadow = 5
            
        hit = False
        
        if sounds:
            sfx_fall.Play()
        
        shake = 0
        
        while not done:
        
            if not ika.Input.right.Position():
                fpsman.render()
            
            timer += 1
            
            sfx_bubbles.volume = min(.4, float(timer)/100)
            
            squid_scale = min(1, squid_scale * 1.02)
            
            if squid_scale != 1 or squid_ang > 20:
                squid_ang = (squid_ang % 360) + 20
            else:
                if not hit:
                    if sounds:
                        sfx_splat.Play()
                    hit = True
                    shake = 50
                squid_ang = 0
                
            i_ang += 7
            k_ang += 3
            a_ang += 10
            ex_ang += 5
            
            shake *= .8
            if shake < 1:
                shake = 0
                
            i_add = abs(math.cos(math.radians(i_ang+90))) * i_spd
            k_add = abs(math.cos(math.radians(k_ang+90))) * k_spd
            a_add = abs(math.cos(math.radians(a_ang+90))) * a_spd
            ex_add = abs(math.cos(math.radians(ex_ang+90))) * ex_spd
            
            i_x = min(i_final[0], i_x + i_add)
            k_x = min(k_final[0], k_x + k_add)
            a_x = min(a_final[0], a_x + a_add)
            ex_x = min(ex_final[0], ex_x + ex_add)
            
            i_y = i_final[1] - abs(math.sin(math.radians(i_ang))) * i_jump
            k_y = k_final[1] - abs(math.sin(math.radians(k_ang))) * k_jump
            a_y = a_final[1] - abs(math.sin(math.radians(a_ang))) * a_jump
            ex_y = ex_final[1] - abs(math.sin(math.radians(ex_ang))) * ex_jump
            
            i_jump = max(min_jump, i_jump - .2)
            k_jump = max(min_jump, k_jump - .2)
            a_jump = max(min_jump, a_jump - .2)
            ex_jump = max(min_jump, ex_jump - .2)
            
            if sounds:
                if (i_ang % 180) < 7:
                    sfx_thud[0].Play()
                if (k_ang % 180) < 3:
                    sfx_thud[1].Play()
                if (a_ang % 180) < 10:
                    sfx_thud[2].Play()
                if (ex_ang % 180) < 5:
                    sfx_thud[3].Play()
                
            if not timer % 2:
            
                if len(i_old_pos) > num_shadow:
                    i_old_pos.pop()
                if len(k_old_pos) > num_shadow:
                    k_old_pos.pop()
                if len(a_old_pos) > num_shadow:
                    a_old_pos.pop()
                if len(ex_old_pos) > num_shadow:
                    ex_old_pos.pop()
                    
                i_old_pos.insert(0, (i_x, i_y))
                k_old_pos.insert(0, (k_x, k_y))
                a_old_pos.insert(0, (a_x, a_y))
                ex_old_pos.insert(0, (ex_x, ex_y))
            
            if i_jump + k_jump + a_jump + ex_jump == min_jump * 4:
                done = True
                
            # ---
            
            ika.Video.DrawRect(0, 0, ika.Video.xres, ika.Video.yres, bg, True)
            
            handleBubbles()
            
            rotate.RotateBlit(squid_img, squid_cx, squid_cy, math.radians(squid_ang), squid_scale)
            #squid_img.Blit(squid_x, squid_y)
            
            wholeAlpha = max(0, wholeAlpha - fadeSpeed)
            
            alphaInc = 255 / num_shadow
            
            for i in reversed(range(len(i_old_pos))):
                ika.Video.TintBlit(i_img, i_old_pos[i][0], i_old_pos[i][1], ika.RGB(255,255,255, 255 - alphaInc * i))
            for i in reversed(range(len(k_old_pos))):
                ika.Video.TintBlit(k_img, k_old_pos[i][0], k_old_pos[i][1], ika.RGB(255,255,255, 255 - alphaInc * i))
            for i in reversed(range(len(a_old_pos))):
                ika.Video.TintBlit(a_img, a_old_pos[i][0], a_old_pos[i][1], ika.RGB(255,255,255, 255 - alphaInc * i))
            for i in reversed(range(len(ex_old_pos))):
                ika.Video.TintBlit(ex_img, ex_old_pos[i][0], ex_old_pos[i][1], ika.RGB(255,255,255, 255 - alphaInc * i))
        
            shake_x = ika.Random(-shake, shake+1)
            shake_y = ika.Random(-shake, shake+1)
            
            ika.Video.ScaleBlit(ika.Video.GrabImage(0, 0, 320, 240), shake_x, shake_y, ika.Video.xres, ika.Video.yres)
            
            if fade:
                ika.Video.DrawRect(0, 0, ika.Video.xres, ika.Video.yres, ika.RGB(0,0,0, wholeAlpha), True)
            
            ika.Video.ShowPage()
            ika.Input.Update()
            
            if button and button.Pressed():
                sfx_bubbles.Pause()
                sfx_fall.Pause()
                return
    
    else:
        
        handleBubbles()
        for b in bubbles:
            b.y = ika.Random(0, 320)
    # ---
    # wait
    
    squid_x, squid_y = squid_final
    i_x, i_y = i_final
    k_x, k_y = k_final
    a_x, a_y = a_final
    ex_x, ex_y = ex_final
    
    timer = 0
    fpsman.sync()
    
    squid_ang_mod = -30
    i_ang_mod = 15
    k_ang_mod = -15
    a_ang_mod = -20
    ex_ang_mod = 10
    
    squid_ang, i_ang, k_ang, a_ang, ex_ang = (0,)*5
    
    animSpd = 20
    
    while time is None or timer <= time:
        
        if not ika.Input.right.Position():
            fpsman.render()
        
        if timer <= 40 and not timer % 10 and sounds:
            sfx_giggle[timer/10].Play()
        
        tick = timer % animSpd
        
        timer += 1
        
        if i_old_pos:
            i_old_pos.pop(0)
        if k_old_pos:
            k_old_pos.pop(0)
        if a_old_pos:
            a_old_pos.pop(0)
        if ex_old_pos:
            ex_old_pos.pop(0)
            
        # ---
        
        ika.Video.DrawRect(0, 0, ika.Video.xres, ika.Video.yres, bg, True)
        
        handleBubbles()
        
        wholeAlpha = max(0, wholeAlpha - fadeSpeed)
        
        if not anim_out and time is not None and timer > (time - (255 / fadeSpeed)):
            endAlpha = min(255, endAlpha + fadeSpeed)
            sfx_bubbles.volume = max(sfx_bubbles.volume - .01, 0)
        
        if idle_anim:
            
            if tick == 0:
                squid_ang += squid_ang_mod
                squid_ang_mod = -squid_ang_mod
            if tick == 19:
                i_ang += i_ang_mod
                i_ang_mod = -i_ang_mod
            if tick == 7:
                k_ang += k_ang_mod
                k_ang_mod = -k_ang_mod
            if tick == 15:
                a_ang += a_ang_mod
                a_ang_mod = -a_ang_mod
            if tick == 11:
                ex_ang += ex_ang_mod
                ex_ang_mod = -ex_ang_mod
            
        rotate.RotateBlit(squid_img, squid_cx, squid_cy, math.radians(squid_ang))
        rotate.RotateBlit(i_img, i_x + i_img.width / 2, i_y + i_img.height / 2, math.radians(i_ang))
        rotate.RotateBlit(k_img, k_x + k_img.width / 2, k_y + k_img.height / 2, math.radians(k_ang))
        rotate.RotateBlit(a_img, a_x + a_img.width / 2, a_y + a_img.height / 2, math.radians(a_ang))
        rotate.RotateBlit(ex_img, ex_x + ex_img.width / 2, ex_y + ex_img.height / 2, math.radians(ex_ang))
        
        if scale_x != 1:
            ika.Video.ScaleBlit(ika.Video.GrabImage(0, 0, 320, 240), 0, 0, ika.Video.xres, ika.Video.yres)
        
        if fade:
            ika.Video.DrawRect(0, 0, ika.Video.xres, ika.Video.yres, ika.RGB(0,0,0, min(255, wholeAlpha + endAlpha)), True)
        
        ika.Video.ShowPage()
        ika.Input.Update()
        
        if button and button.Pressed():
            if time is None:
                break
            else:
                sfx_bubbles.Pause()
                sfx_fall.Pause()
                return
    
    # ---
    # fade out
    
    squid_x, squid_y = squid_final
    i_x, i_y = i_final
    k_x, k_y = k_final
    a_x, a_y = a_final
    ex_x, ex_y = ex_final
    
    timer = 0
    
    squid_ang = 0
    
    for b in bubbles:
        b.x_spd = ika.Random(0,2) * 2 - 1
    
    alphaInc = 255 / 110
    bg = ika.GetRGB(bg)[:3]
    fpsman.sync()
    
    squid_cx = squid_x + squid_img.width / 2
    squid_cy = squid_y + squid_img.height / 2
    
    squid_scale = 1
    
    squid_spd = 1.5
    squid_turn_times = [30, 50, 70, 100, 110, 126, 128, 129, 130, 140, 150]
    squid_turn_amts = [1, 2, 3, 5, 11, 8, 4, 0, -4, -3, -2]
    
    if anim_out:
        
        if sounds:
            sfx_splash.Play()
        
        while timer <= 150:
            
            if not ika.Input.right.Position():
                fpsman.render()
            
            #Bubble.x_rand = int(timer / 2)
            
            timer += 1
            
            # ---
            
            if timer > 50:
                sfx_bubbles.volume = max(sfx_bubbles.volume - .005, 0)
            
            inc = (timer ** 1.5)
            i_y += inc / 20
            k_y += inc / 30
            a_y += inc / 40
            ex_y += inc / 50
            
            i_x *= 1.001
            k_x *= 1.002
            a_x *= 1.003
            ex_x *= 1.004
            
            squid_spd *= 1.025
            squid_scale *= .995
            squid_cx += math.cos(math.radians(squid_ang - 60)) * squid_spd
            squid_cy += math.sin(math.radians(squid_ang - 60)) * squid_spd
            
            for i in range(len(squid_turn_times)):
                if timer < squid_turn_times[i]:
                    squid_ang += squid_turn_amts[i]
                    break
            alpha = max(0, 255 - (alphaInc * timer))
            ika.Video.DrawRect(0, 0, ika.Video.xres, ika.Video.yres, ika.RGB(*bg + (alpha,)), True)
            
            handleBubbles(False)
            
            #squid_img.Blit(squid_x, squid_y)
            rotate.RotateBlit(squid_img, squid_cx, squid_cy, math.radians(squid_ang), squid_scale)
            
            i_img.Blit(i_x, i_y)
            k_img.Blit(k_x, k_y)
            a_img.Blit(a_x, a_y)
            ex_img.Blit(ex_x, ex_y)
            
            if scale_x != 1:
                ika.Video.ScaleBlit(ika.Video.GrabImage(0, 0, 320, 240), 0, 0, ika.Video.xres, ika.Video.yres)
                
            ika.Video.ShowPage()
            ika.Input.Update()
            
            if button and button.Pressed():
                sfx_bubbles.Pause()
                sfx_fall.Pause()
                return
        
    sfx_bubbles.Pause()
    